#include "card.h"
#include "baseactor.h"
#include "containor.h"
#include "drawer.h"
#include "updater.h"

Card::Card() : CardUpdaterInterface() {}
Card::Card(CardAttr attr) : CardUpdaterInterface(), attribute(attr), buffer(attr), NoBackGround(false) {}
Card::Card(Coord_t pos, Coord_t size, const String_t& title, const String_t& con, char border, char fill)
    : CardUpdaterInterface(), NoBackGround(false), attribute(pos, size, title, con, border, fill), buffer(attribute)
{
    // printf("Card:\ntitle:%s\n content:%s\n border:%c\n fill:%c\nn", title.data(), con.data(), border, fill);
}
Card::Card(Coord_t pos, Coord_t size, const String_t& title, const String_t& con, char border, char fill, Drawer* ptr)
    : CardUpdaterInterface(), NoBackGround(false), attribute(pos, size, title, con, border, fill), buffer(attribute),
      Component(ptr)
{
    // printf("Card:\ntitle:%s\n content:%s\n border:%c\n fill:%c\nn", title.data(), con.data(), border, fill);
}
Card::~Card() {}

Action_t Card::Commit()
{
    // if (attribute != buffer)
    attribute = buffer;
    return 0;
}
Action_t Card::Rollback()
{
    // if (attribute != buffer)
    buffer = attribute;
    return 0;
}

Action_t Card::Zerolize()
{
    return this->Position(ZERO).Size(ZERO).Commit();
}

void Card::render()
{
    CardAttr& object{attribute};
    short& X{attribute.offset.X};
    short& Y{attribute.offset.Y};
    Coord_t pos{LocalPos.append(object.pos)};
    Coord_t size{LocalSize.append(object.size)};
    // pos.Y -= 2;
    // size.X -= 2;
    // size.Y -= 2;

    // TODO: use _temp memberVar to replace these true tempvar
    //_tempTitle = TextAttr{{_.pos.append(1, 1)}, _.title, {short(_.size.X - 2), short(_.size.Y - 2)}, true};
    //_tempContent = TextAttr{{_.pos.append(1, 3)}, _.content, _.size.append(-2, -4), false};
    // printf("rendering Card: 0x%p\n", this);
    if (!NoBackGround) ptr_drawer->Square(pos, size, object.background, true);
    ptr_drawer->text(pos.append(X + 1, 1), object.title, size.append(-2 - X - X, 1), true);
    ptr_drawer->text(pos.append(X + 1, 3 + Y), object.content, size.append(-2 - X - X, -4 - Y - Y), false);
    ptr_drawer->Xline(pos.append(1, 2), short(size.X - 2), '-');
    ptr_drawer->Square(pos, size, '-', object.border, '+', false);
}
//++++++++++++++++++
void Card::bindDrawer(Drawer* ptr)
{
    this->ptr_drawer = ptr;
}
using CardUDIF = CardUpdaterInterface;
CardUDIF& Card::Position(Coord_t pos)
{
    this->buffer.pos = pos;
    return *this;
}
CardUDIF& Card::Size(Coord_t size)
{
    this->buffer.size = size;
    return *this;
}
CardUDIF& Card::Title(String_t& str)
{
    this->buffer.title = str;
    return *this;
}
CardUDIF& Card::Content(String_t& str)
{
    this->buffer.content = str;
    return *this;
}
CardUDIF& Card::BorderStyle(char c)
{
    this->buffer.border = c;
    return *this;
}
CardUDIF& Card::FillStyle(char c)
{
    if (c == '\0')
    {
        this->buffer.background = ' ';
        NoBackGround = true;
        return *this;
    }
    else
    {
        this->buffer.background = c;
        return *this;
    }
}
CardUDIF& Card::Offset(Coord_t offset)
{
    this->buffer.offset = offset;
    return *this;
}

Action_t Card::SetFather(Containor* ptr)
{
    father = ptr;
    return 0;
}
void Card::UpdateChildCoord(Component*, Component*, Component*, Component*)
{
    return;
}